`timescale 1ns/1ps
`default_nettype none

/* NOTE:
* - 将图像数据写入SDRAM
*/

//`define ENABLE_HUB_PORT_OFFSET

module pixel_save_top_sdram (
    // system signal
    input  wire         I_sclk,  // 125M
    input  wire         I_sdram_clk, // 150M
    input  wire         I_rst_n,
    //config
    input  wire         I_cfg_light_adj_en,  // 全局亮度调整
    input  wire         I_cfg_temp_adj_en,   // 全局色温调整
    input  wire         I_cfg_color_adj_en,  // 全局色度调整
    input  wire         I_cfg_pixel_adj_en,  // 逐点色度调整
    input  wire         I_cfg_gap_adj_en,    // 缝隙调整
    input  wire [15:0]  I_cfg_temp_coe_r,    // 色温调整系数
    input  wire [15:0]  I_cfg_temp_coe_g,    // 色温调整系数
    input  wire [15:0]  I_cfg_temp_coe_b,    // 色温调整系数
    input  wire [15:0]  I_cfg_light_coe,     // 整体亮度系数
    input  wire [15:0]  I_cfg_color_coe_r0,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_g0,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_b0,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_r1,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_g1,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_b1,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_r2,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_g2,  // 全局色度调整系数
    input  wire [15:0]  I_cfg_color_coe_b2,  // 全局色度调整系数
    input  wire         I_cfg_contrast_en,   // 对比度使能
    input  wire [7:0]   I_cfg_contrast_coe,  // 对比度系数
    
    input  wire         I_cfg_pixel_adj_mode,     
    input  wire [1:0]   I_cfg_scan_mode,
    input  wire [1:0]   I_cfg_box_dir,       // 箱体方向
    input  wire [1:0]   I_cfg_col_loop,      // 列模式读取循环次数(数据组数/8,向上取整)
    input  wire [7:0]   I_cfg_col_step,      // 列模式每次读地址间隔
    input  wire [7:0]   I_cfg_port_height,
    input  wire [3:0]   I_cfg_block_max,
    // config
    input  wire [9:0]   I_cfg_scan_length, // 一扫的像素数量（包含虚点）
    input  wire [5:0]   I_cfg_port_max,
    input  wire [5:0]   I_cfg_scan_max,
    input  wire [3:0]   I_cfg_sector_count,
    input  wire [9:0]   I_cfg_sector_width,
    input  wire [9:0]   I_cfg_sector_height,
    input  wire [10:0]  I_cfg_win_col_num,   // 带载列数（宽度）
    input  wire [10:0]  I_cfg_win_row_num,   // 带载行数（高度）
    // port map
    output wire         O_port_map_rden,
    output wire [7:0]   O_port_map_addr,
    input  wire [15:0]  I_port_map_q,
    
    
    // gamma
    output wire         O_gamma_start,
    output wire [7:0]   O_gamma_data,
    input  wire [15:0]  I_gamma_result,
    // gap info
    output wire         O_gap_coe_req,
    output wire [9:0]   O_gap_coe_row,
    input  wire         I_gap_coe_busy,
    output wire         O_gap_coe_ack,
    input  wire [15:0]  I_gap_coe_val,
    // input frame
    input  wire         I_frame_start,
    input  wire [1:0]   I_frame_id,  // 用于选定第二次SDRAM SDRAM存储区
    input  wire         frame_req,
    input  wire [1:0]   frist_frame,//第一次SDRAM的切换
  
    //sdram mux  one read
    output wire         O_read_sdram_req,
    input  wire         I_read_sdram_ack,
    input  wire         I_read_sdram_irq,
    output wire         O_read_sdram_cs_n,
    output wire         O_read_sdram_ras_n,
    output wire         O_read_sdram_cas_n,
    output wire         O_read_sdram_we_n,
    output wire [1:0]   O_read_sdram_ba,
    output wire [10:0]  O_read_sdram_addr,
    output wire [31:0]  O_read_sdram_dq_out,
    input  wire [31:0]  I_read_sdram_dq_in,
    output wire         O_read_sdram_dq_oe,
    output wire [3:0]   O_read_sdram_dqm,
    
    // sdram mux two write
    output wire         O_write_sdram_req,
    input  wire         I_write_sdram_ack,
    input  wire         I_write_sdram_irq,
    output wire         O_write_sdram_cs_n,
    output wire         O_write_sdram_ras_n,
    output wire         O_write_sdram_cas_n,
    output wire         O_write_sdram_we_n,
    output wire [1:0]   O_write_sdram_ba,
    output wire [10:0]  O_write_sdram_addr,
    output wire [31:0]  O_write_sdram_dq_out,
    input  wire [31:0]  I_write_sdram_dq_in,
    output wire         O_write_sdram_dq_oe,
    output wire [3:0]   O_write_sdram_dqm
);
//------------------------Parameter----------------------

//------------------------Local signal-------------------
wire        req_sr;
// pixel_crop
wire        line_start;
wire        line_end;
wire [9:0]  line_num;
wire        pixel_valid;
wire [9:0]  pixel_col;
wire [23:0] pixel_gray;

wire        line_start_2;
wire        line_end_2;
wire [9:0]  line_num_2;
wire        pixel_valid_2;
wire [9:0]  pixel_col_2;
wire [23:0] pixel_gray_2;

// line output
wire        row_start;
wire [9:0]  row_num;
wire        row_ready;
wire        row_ack;
wire        pixel_req;
wire [7:0]  pixel_data;

// pixel_writer_top
wire        write_start;
wire        write_busy;
wire [20:0] write_addr;
wire [5:0]  write_len;
wire [7:0]  write_data;

//line_row_buf
wire    line_start_buf;
wire    line_end_buf  ;
wire        ram_wclk;
wire        ram_wren;
wire [9:0]  ram_addr;
wire [23:0] ram_data;

//to save_ctrl
wire        row_start_ctrl  ;
wire        row_ready_ctrl  ;
wire        row_ack_ctrl    ;
wire        pixel_req_ctrl ;
wire [7:0]  pixel_data_ctrl;

//pixel_gray_reader
wire         read_req;
wire         read_busy;
wire         frame_enable;
wire         read_req_sr;
wire         coe_load_req;
wire         coe_load_busy;
wire         intial_valu;
wire         coe_read_sr;
wire         pre_read    ;
wire         pre_read_r  ;
wire [31:0]  coe_ram_data;
//coe
wire         pixel_coe_ack;
wire [15:0]  pixel_coe_r;
wire [15:0]  pixel_coe_g;
wire [15:0]  pixel_coe_b;

//------------------------Instantiation------------------
// coe_reader
coe_reader coe_rd (/*{{{*/
    .I_sclk             (I_sclk ),
    .I_sdram_clk        (I_sdram_clk ),
    .I_rst_n            (I_rst_n ),
    .I_cfg_coe_mode     (I_cfg_pixel_adj_mode ),
    .I_cfg_scan_length  (I_cfg_scan_length   ), //  一行的像素 1 计数
    .I_coe_load_req     (coe_load_req ),
    .I_coe_load_busy    (coe_load_busy ),
    .I_coe_ack          (pixel_coe_ack ),
    .I_intial_valu      (intial_valu),
    .I_coe_read_sr      (coe_read_sr),
    .I_pre_read         (pre_read   ),
    .I_ram_wdata        (coe_ram_data ),
    .I_pre_read_r       (pre_read_r  ),

    .O_coe_r            (pixel_coe_r ),
    .O_coe_g            (pixel_coe_g ),
    .O_coe_b            (pixel_coe_b )
);/*}}}*/
// 第一次读SDRAM
//pixel_gray_reader
pixel_gray_reader reader(/*{{{*/
    .I_sclk             (I_sclk             ),          //
    .I_sdram_clk        (I_sdram_clk        ),          //
    .I_rst_n            (I_rst_n            ),
    .I_frame_start      (frame_req          ), //(I_frame_start      ),
                
    .line_max_pixel     (I_cfg_scan_length  ),
    .I_cfg_sector_width (I_cfg_sector_width ),//分区宽度
    .I_cfg_sector_count (I_cfg_sector_count ),
    .I_cfg_sector_height(I_cfg_sector_height),
    .I_cfg_box_dir      ( I_cfg_box_dir     ),
    .I_cfg_port_max     (I_cfg_port_max     ),
    .I_cfg_scan_max     (I_cfg_scan_max     ),
    .I_cfg_port_height  (I_cfg_port_height  ),
    .I_cfg_block_max    (I_cfg_block_max    ),
    .I_cfg_win_col_num  ( I_cfg_win_col_num ),
    .I_cfg_win_row_num  ( I_cfg_win_row_num ),
    //coe
    .I_coe_load_req     (coe_load_req       ),
    .I_cfg_coe_mode     (I_cfg_pixel_adj_mode ),
    .O_coe_load_busy    (coe_load_busy      ),    
    .O_intial_valu      (intial_valu        ),
    .O_coe_read_sr      (coe_read_sr        ),
    .O_pre_read         (pre_read           ),
    .O_pre_read_r       (pre_read_r         ),
    .O_coe_ram_data     (coe_ram_data       ),
    .I_cfg_pixel_adj_en (I_cfg_pixel_adj_en  ),

    .I_read_req         (read_req           ), // 读第一次 SDRAM 的请求信号   
    .O_read_busy        (read_busy          ),   
    .I_frame_req        (frame_req          ), // 写完一帧来的请求命令。
    .frist_frame        (frist_frame        ),
    .O_frame_enable     (frame_enable       ),
    // line_row_buf     
    .O_ram_wclk         (ram_wclk           ),
    .O_ram_wren         (ram_wren           ),
    .O_ram_addr         (ram_addr           ),
    .O_ram_data         (ram_data           ),              
    .O_row_start        (line_start_buf     ),
    .O_row_end          (line_end_buf       ),
    //SDRAM 接口               
    .O_mux_req          (O_read_sdram_req   ),
    .I_mux_ack          (I_read_sdram_ack   ),
    .I_mux_irq          (I_read_sdram_irq   ), // 中端
    .O_mux_cs_n         (O_read_sdram_cs_n  ),
    .O_mux_ras_n        (O_read_sdram_ras_n ),
    .O_mux_cas_n        (O_read_sdram_cas_n ),
    .O_mux_we_n         (O_read_sdram_we_n  ),
    .O_mux_ba           (O_read_sdram_ba    ),
    .O_mux_addr         (O_read_sdram_addr  ),
    .O_mux_dq_out       (O_read_sdram_dq_out),
    .I_mux_dq_in        (I_read_sdram_dq_in ),
    .O_mux_dq_oe        (O_read_sdram_dq_oe ),
    .O_mux_dqm          (O_read_sdram_dqm   )
);/**}}}*/

//第一次从SDRAM 读出一行的数据存进buf 里面
line_row_buf line_row_buf_inst(/*{{{*/
    .I_sclk(I_sclk),  // 12 
    .I_rst_n(I_rst_n),
    
    .I_frame_start  (frame_req) , //(I_frame_start),
    //pixel_gray_reader
    .I_line_start   (line_start_buf), 
    .I_line_end     (line_end_buf       ),   
    .I_pixel_valid  (ram_wren),
    .I_pixel_col    (ram_addr   ),  
    .I_pixel_gray   (ram_data),
    .I_pixel_clk    (ram_wclk),
    .O_read_req     (req_sr), 
     // save_ctrl
    .O_row_start    (row_start_ctrl ),  
    .O_row_ready    (row_ready_ctrl ),  
    .I_row_ack      (row_ack_ctrl   ),    
    .I_pixel_req    (pixel_req_ctrl ),  //读buf请求
    .O_pixel_data   (pixel_data_ctrl)    //buf数据
);
/*}}}*/

// pixel_save_ctrl
//读出写一行buf 的数据的控制信号，以及开始存第二次sdram的控制
pixel_save_ctrl_3sdram  pixel_save_ctrl_3sdram_inst(
    .I_sclk             (I_sclk             ),
    .I_rst_n            (I_rst_n            ),
                        
    .I_frame_start      (frame_req), //(I_frame_start      ),                 
    .frame_buf_sel      (I_frame_id         ), //帧切换  
    .I_cfg_scan_mode    ( I_cfg_scan_mode ),                
    .I_cfg_pixel_adj_en (I_cfg_pixel_adj_en  ),
    .I_cfg_gap_adj_en   (I_cfg_gap_adj_en    ),
    .I_cfg_scan_length  (I_cfg_scan_length   ), //  一行的像素 1 计数
    .I_cfg_scan_max     (I_cfg_scan_max      ),//0计数
    .I_cfg_port_max     (I_cfg_port_max      ),//0计数                
    .O_coe_load_req     (coe_load_req        ),
    .O_coe_load_row     (                    ),
    .I_coe_load_busy    (coe_load_busy       ),                
    .O_gap_coe_req      (O_gap_coe_req       ),
    .O_gap_coe_row      (O_gap_coe_row       ),
    .I_gap_coe_busy     (I_gap_coe_busy      ),
    //line_row_buf                                    
    .I_row_start        (row_start_ctrl      ), 
    .I_row_ready        (row_ready_ctrl      ), 
    .O_row_ack          (row_ack_ctrl        ), 
    .O_pixel_req        (pixel_req_ctrl      ), 
    .I_pixel_data       (pixel_data_ctrl     ), 
    .O_read_req         (read_req_sr       ),   
    .O_write_start      (write_start    ), 
    .I_write_busy       (write_busy     ), 
    .O_write_addr       (write_addr     ), 
    .O_write_len        (write_len      ), 
    .O_write_data       (write_data     )  
);


// pixel_writer_top
pixel_writer_top writer (/*{{{*/
    .I_sclk             ( I_sclk ),
    .I_sdram_clk        ( I_sdram_clk ),
    .I_rst_n            ( I_rst_n ),
    .I_cfg_scan_mode    ( I_cfg_scan_mode ),
    .I_cfg_box_dir      ( /*I_cfg_box_dir*/0 ),
    .I_cfg_col_loop     ( I_cfg_col_loop ),
    .I_cfg_light_adj_en ( I_cfg_light_adj_en ),
    .I_cfg_temp_adj_en  ( I_cfg_temp_adj_en ),
    .I_cfg_color_adj_en ( I_cfg_color_adj_en ),
    .I_cfg_pixel_adj_en ( I_cfg_pixel_adj_en ),
    .I_cfg_gap_adj_en   ( I_cfg_gap_adj_en ),
    .I_cfg_temp_coe_r   ( I_cfg_temp_coe_r ),
    .I_cfg_temp_coe_g   ( I_cfg_temp_coe_g ),
    .I_cfg_temp_coe_b   ( I_cfg_temp_coe_b ),
    .I_cfg_light_coe    ( I_cfg_light_coe ),
    .I_cfg_color_coe_r0 ( I_cfg_color_coe_r0 ),
    .I_cfg_color_coe_g0 ( I_cfg_color_coe_g0 ),
    .I_cfg_color_coe_b0 ( I_cfg_color_coe_b0 ),
    .I_cfg_color_coe_r1 ( I_cfg_color_coe_r1 ),
    .I_cfg_color_coe_g1 ( I_cfg_color_coe_g1 ),
    .I_cfg_color_coe_b1 ( I_cfg_color_coe_b1 ),
    .I_cfg_color_coe_r2 ( I_cfg_color_coe_r2 ),
    .I_cfg_color_coe_g2 ( I_cfg_color_coe_g2 ),
    .I_cfg_color_coe_b2 ( I_cfg_color_coe_b2 ),
    .I_cfg_contrast_en  ( I_cfg_contrast_en ),
    .I_cfg_contrast_coe ( I_cfg_contrast_coe ),
    .O_pixel_coe_ack    ( pixel_coe_ack ),
    .I_pixel_coe_r      ( pixel_coe_r ),
    .I_pixel_coe_g      ( pixel_coe_g ),
    .I_pixel_coe_b      ( pixel_coe_b ),
    .O_gamma_start      ( O_gamma_start ),
    .O_gamma_data       ( O_gamma_data ),
    .I_gamma_result     ( I_gamma_result ),
    .O_gap_coe_ack      ( O_gap_coe_ack ),
    .I_gap_coe_val      ( I_gap_coe_val ),
    
    .I_write_start      ( write_start ),
    .O_write_busy       ( write_busy ),
    .I_write_addr       ( write_addr ),
    .I_write_len        ( write_len  ),
    .I_write_data       ( write_data ),
    
    .O_mux_req          ( O_write_sdram_req    ),
    .I_mux_ack          ( I_write_sdram_ack    ),
    .I_mux_irq          ( I_write_sdram_irq    ),
    .O_mux_cs_n         ( O_write_sdram_cs_n   ),
    .O_mux_ras_n        ( O_write_sdram_ras_n  ),
    .O_mux_cas_n        ( O_write_sdram_cas_n  ),
    .O_mux_we_n         ( O_write_sdram_we_n   ),
    .O_mux_ba           ( O_write_sdram_ba     ),
    .O_mux_addr         ( O_write_sdram_addr   ),
    .O_mux_dq_out       ( O_write_sdram_dq_out ),
    .I_mux_dq_in        ( I_write_sdram_dq_in  ),
    .O_mux_dq_oe        ( O_write_sdram_dq_oe  ),
    .O_mux_dqm          ( O_write_sdram_dqm    )
);/*}}}*/

//------------------------Body---------------------------
assign read_req     = frame_req ||(frame_enable &&read_req_sr ) || coe_load_req;//读第一次SDRAM 请求

endmodule

`default_nettype wire

// vim:set ts=4 sw=4 et fenc=utf-8 fdm=marker:
